home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Collections: MegaDisc
/
MegaDisc 27 (1992-03)(MegaDisc Digital Publishing)(AU)(Disk 2 of 2).zip
/
MegaDisc 27 (1992-03)(MegaDisc Digital Publishing)(AU)(Disk 2 of 2).adf
/
AMOS
/
Dos_in_AMOS
/
Dos_in_AMOS
Wrap
Text File
|
1992-03-30
|
21KB
|
653 lines
Using AmigaDOS From Within AMOS
by Graham Clowes
Bio-pic:
I am an electrician by trade with an Industrial Electronics Diploma, but
have not worked in either of these fields for more than a decade. My
present position is Production Officer with Pacific Power. I am one of
those people dedicated to ensuring that there is plenty of power to keep
our Amigas running long into the night. I built my first computer back in
the early seventies when integrated circuits were a relatively new
technology from a kit provided by Dick Smith Electronics. It had a massive
256 bytes of memory and was programmed by rows of switches on the front
panel. How things have progressed! I now own two Amigas a 500 and a 2000
each with a 20meg hd and 3 megs. My interests at present are turning
towards graphics digitising and 24bit in particular. My aim is to begin a
library of images and history of the Lithgow and Illawarra regions and
perhaps progress from there. It depends a lot on time, which I will not
have much of during the next 4-6 months. I have recently developed an
interest in 'C' so any articles you may provide on this topic will be most
avidly read. Keep up the good work and hopefully it won't be too long
before I have something else to send.
(( 27 )) (( 27 )) (( 27 )) (( 27 )) (( 27 )) (( 27 )) (( 27 )) (( 27 ))
On careful reading of the AMOS manual, you will find at the back of the
book a section on accessing the system libraries. These functions enable
you to utilise the Amiga's internal system libraries. One of these
libraries is the 'dos.library'. This library provides communication with
the disk drives and the hard disk. It also enables you to open windows in
the CLI environment and communicate with the user without opening an AMOS
screen. By combining these features it is a relatively simple matter to
communicate with the DOS to provide features not provided by AMOS.
Provided here are a number of procedures which may be included in your own
programs or used as accessories to provide some of the workbench disk
functions. This is by no means an exhaustive list of the functions
available to you. You should experiment and find out which functions are
of use to you. By using the Execute function in the 'dos.library' you will
be able to utilise most of the commands in the 'c' drawer, but remember, if
the command needs user input you will need to open a window as shown in the
example to format a disk. The various library offsets and system constants
can be obtained from the
AMIGA ROM KERNEL
REFERENCE MANUAL
.
Formatting a Disk
You will need the 'Format' command in the System drawer to use the
procedure described below. This procedure may be used in your own programs
or loaded as an accessory.
The first requirement is a window; as the AmigaDOS Format command, as
provided in the system drawer of your workbench disk, needs to tell you
what's going on.
Amos To Back
First let's move AMOS to the back so we can see our
window.
_MODE_OLD=1005
Mode old should be used when opening a window. If you
_OPEN=-30
are opening a new file on disk, you should use mode new
_CLOSE=-36
1006. _OPEN, _CLOSE and _EXECUTE are the dos.library
_EXECUTE=-222
offsets. These figures can be obtained from the 'Amiga
ROM KERNEL Reference Manual'.
FILE$="CON:66/10/508/50/** AMOS Format G Clowes 22-12-91 **"
Our window will need a name. We will use the variable FILE$ to
hold this. The name consists of:-
the kind of device we are opening -> '
CON:
'
the top left corner of the window -> '
66
','
10
'
the size of the window -----------> '
508
' by '
50
'
and finally the name itself.
The backslash '/' is just to separate the various values.
Dreg(1)=Varptr(FILE$)
Now the DOS must be told where our command is.
We pass the address of the variable FILE$ to
data register D1, an internal register of the
CPU.
Dreg(2)=_MODE_OLD
Next we tell DOS what Mode to use. We pass this
value on to data register D2.
_WINDOW=Doscall(_OPEN)
The 'dos.library' now has the information it
requires to successfully open our window. If the
function was successful it will return the
address of our window. This is known as the
filehandle. If our window failed to open, a zero
would be returned.
If _WINDOW=0 Then Pop Proc
Obviously if we have not been able to open a
window we can not continue. Exit the procedure.
COMMAND$="System/Format DRIVE "+DISK$+" NAME "+NAME$
Once we have our window, we can proceed to
format the disk. We will use the variable
COMMAND$ to hold the command we wish to execute.
If Not ICONS Then COMMAND$=COMMAND$+" NOICONS"
If the variable ICONS=False then we add
'NOICONS' to the end of our command string. This
prevents the placing of the Trashcan folder on
the disk.
Dreg(1)=Varptr(COMMAND$)
Tell DOS where our command is. This is
passed to data register D1.
Dreg(2)=0
We should tell the function where its input
should come from. In this case we won't bother as
it's not really required. But if you need user
input you would place the filehandle of the
window here.
Dreg(3)=_WINDOW
The DOS will need to know where to send its
output. In this case we give it the filehandle
of our window.
R=Doscall(_EXECUTE)
Execute the command. This function is similar to
the 'run' command you would use from the CLI.
'R' will equal zero if the function failed.
Dreg(1)=_WINDOW
After we have formatted our disk, we will no
longer need the window. We pass the handle of
the window in data register D1.
R=Doscall(_CLOSE)
This call now closes the window.
Amos To Front
Now let's get back to AMOS and some serious
programming.
DISK$ = The disk drive you wish to format
NAME$ = The Name you wish to give the disk.
ICONS = True disk will have a trashcan.
False disk will not have a trashcan.
e.g. _FORMAT["df1:","TESTING",False]
===================================================================
To include in your own programs, simply cut and merge as
ASCII.
Procedure _FORMAT[DISK$,NAME$,ICONS]
Amos To Back
_MODE_OLD=1005
_OPEN=-30
_CLOSE=-36
_EXECUTE=-222
FILE$="CON:66/10/508/50/** AMOS Format G Clowes 22-12-91 **"
Dreg(1)=Varptr(FILE$)
Dreg(2)=_MODE_OLD
_WINDOW=Doscall(_OPEN)
If _WINDOW=0 Then Pop Proc
COMMAND$="System/Format DRIVE "+DISK$+" NAME "+NAME$
If Not ICONS Then COMMAND$=COMMAND$+" NOICONS"
Dreg(1)=Varptr(COMMAND$)
Dreg(2)=0
Dreg(3)=_WINDOW
R=Doscall(_EXECUTE)
Dreg(1)=_WINDOW
R=Doscall(_CLOSE)
Amos To Front
End Proc
Getting the System Time
AmigaBASIC provides the functions 'DATE$' and "TIME$' to retrieve the
system date and time. Unfortunately these facilities are not available
in AMOS. There is however a 'Date' command in the 'C' drawer and, as
noted above, AMOS provides easy access to the 'dos.library' to enable
us to use this command. The system time can also be found by use of the
DateStamp function, but we will look at that later.
_MODE_NEW=1006
Mode new (1006) should be used when opening a
_OPEN=-30
new file. _OPEN, _CLOSE and _EXECUTE are the
_CLOSE=-36
dos.library functions we will use.
_EXECUTE=-222
TEMP$="RAM:Date"
The AmigaDOS 'Date' command needs somewhere to
send its output. We will therefore open a
temporary file on the RAM DISK.
Dreg(1)=Varptr(TEMP$)
Tell DOS about our file name. Pass the address
of the variable TEMP$ in data register D1.
Dreg(2)=_MODE_NEW
Which mode shall we require? Let's place that
in data register D2.
FILEHANDLE=Doscall(_OPEN)
The 'dos.library' now has the information it
requires to successfully open our file. If it
was successful the filehandle will be returned
in the variable FILEHANDLE.
If FILEHANDLE=0 Then Pop Proc
If we failed to open a file then we can not
continue so exit the procedure.
COMMAND$="Date"
We will use the variable COMMAND$ to hold the
command we wish to execute.
Dreg(1)=Varptr(COMMAND$)
Tell DOS where our command is and place it in
data register D1.
Dreg(2)=0
Give the DOS the handle of the Input channel. In
this case a zero in data register D2.
Dreg(3)=FILEHANDLE
The DOS will need to know where to send its
output. In this case we give it the filehandle
of our temporary file in RAM:.
RESULT=Doscall(_EXECUTE)
Execute the command. RESULT will equal zero if
the function failed.
Dreg(1)=FILEHANDLE
Now that AmigaDOS is finished with our temporary
file we can close it. This does not erase the
R=Doscall(_CLOSE)
file, but makes it available for AMOS to read it
to obtain the time.
Set Input 10,-1
AMOS uses both a Return and a line feed at the
end of each line. AmigaDOS uses only a line feed
. Therefore we must tell AMOS to expect only a
line feed at the end of each line other wise it
gets confused.
If RESULT<>0
If RESULT does not equal zero then the 'Execute'
Open In 1,TEMP$
function succeeded and we will have something
Line Input #1,TIME$
worthwhile to read in our temporary file.
Close 1
Else
TIME$=""
If RESULT equals zero then the call failed and
End If
our temporary file will be empty.
Kill TEMP$
We will no longer require the temporary file so
lets erase it.
End Proc[TIME$]
The procedure returns the system time given by
the Date command.
e.g. TIME
Print Param$
===================================================================
To include in your own programs, simply cut and merge as
ASCII.
Procedure TIME
_MODE_NEW=1006
_OPEN=-30
_CLOSE=-36
_EXECUTE=-222
TEMP$="RAM:Date"
Dreg(1)=Varptr(TEMP$)
Dreg(2)=_MODE_NEW
FILEHANDLE=Doscall(_OPEN)
If FILEHANDLE=0 Then Pop Proc
COMMAND$="Date"
Dreg(1)=Varptr(COMMAND$)
Dreg(2)=0
Dreg(3)=FILEHANDLE
RESULT=Doscall(_EXECUTE)
Dreg(1)=FILEHANDLE
R=Doscall(_CLOSE)
Set Input 10,-1
If RESULT<>0
Open In 1,TEMP$
Line Input #1,TIME$
Close 1
Else
TIME$=""
End If
Kill TEMP$
End Proc[TIME$]
DateStamp
As previously mentioned there is another way to get the system time by
utilising the 'dos.library'. This method requires considerably more
effort. For an output similar to the AmigaDOS 'Date' command a number of
arrays are required to be filled and a number of calculations are
required to convert the three numbers returned by DateStamp into a
recognisable date format. The following procedures return the date as
Monday 28-Feb-91 15:32:34
The 'dos.library' function DateStamp returns the system time as three
long words, that is three 32 bit numbers. The first number contains
the number of days since the first of January 1978. The second holds
the number of minutes since midnight and the last the number of ticks
since the last full minute. One tick is 1/60 of a second. This method
has the advantage of not requiring the Date command from the System
disk.
Dim TIME(3)
We need an array to hold the three 32 bit
numbers returned by DateStamp.
DATESTAMP=-192
The 'dos.library' offset for DateStamp is -192.
Dreg(1)=Varptr(TIME(1))
DateStamp will need to know where to place the
date.
R=Doscall(DATESTAMP)
The call to DateStamp fills the array TIME()
with the current system time.
The procedure CALC_DATE converts the date returned by DateStamp into
the format described above. The calculations required to perform the
transformation I found in the '
Advanced System Programmer's Guide
' by
Abacus
and I converted the 'C' code over to AMOS.
===================================================================
To include in your own programs, simply cut and merge as
ASCII.
Dim TIME(3)
Dreg(1)=Varptr(TIME(1))
R=Doscall(-192)
CALC_DATE
Print Param$
'
Procedure CALC_DATE
Shared TIME()
Data "Jan",31,"Feb",28,"Mar",31,"Apr",30,"May",31,"Jun",30,"Jul",31,"Aug",31
Data "Sep",30,"Oct",31,"Nov",30,"Dec",31
Data "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"
'
R=0
DAYS_1980=2*365
'
'
Dim NAMES_OF_MONTH$(12),DAYS_OF_MONTHS(12),DAYS_OF_WEEK$(7)
For X=1 To 12
Read NAMES_OF_MONTH$(X)
Read DAYS_OF_MONTHS(X)
Next X
For X=1 To 7
Read DAYS_OF_WEEK$(X)
Next X
'
'
'
'
HOURS=TIME(2)/60
_MINUTES=TIME(2) mod 60
SECONDS=TIME(3) mod 60
If TIME(1)>DAYS_1980
Add TIME(1),-DAYS_1980
YEAR=1980
Else
YEAR=1978
If TIME(1)>365
Add TIME(1),-365
Inc YEAR
End If
Goto _GET_MONTH
End If
For LEAP_YEAR=1 To 33
If TIME(1)>366
Add TIME(1),-366
Inc YEAR
End If
For YRS=1 To 3
If TIME(1)>365
Add TIME(1),-365
Inc YEAR
End If
Next YRS
Next LEAP_YEAR
Proc LEAPYEAR[YEAR]
If Param=True Then DAYS_OF_MONTHS(2)=29
_GET_MONTH:
MONTH=1
For X=1 To 12
If TIME(1)>DAYS_OF_MONTHS(X)
Add TIME(1),-DAYS_OF_MONTHS(X)
Inc MONTH
Else
Exit
End If
Next X
DATE=TIME(1)+1
DAY=DATE mod 7
DATE$=Str$(DATE)-" " : If Len(DATE$)<2 Then DATE$="0"+DATE$
DATE$=DAYS_OF_WEEK$(DAY)+" "+DATE$+"-"+NAMES_OF_MONTH$(MONTH)+"-"+Right$(Str$(YEAR),2)
HOUR$=Str$(HOURS)-" " : If Len(HOUR$)<2 Then HOUR$="0"+HOUR$
_MIN$=Str$(_MINUTES)-" " : If Len(_MIN$)<2 Then _MIN$="0"+_MIN$
SEC$=Str$(SECONDS)-" " : If Len(SEC$)<2 Then SEC$="0"+SEC$
TIME$=DATE$+" "+HOUR$+":"+_MIN$+":"+SEC$
End Proc[TIME$]
'
Procedure LEAPYEAR[YEAR]
If(YEAR/4)*4=YEAR and(YEAR/100)*100=YEAR Then FLAG=True Else FLAG=False
End Proc[FLAG]
Examine
This function fills a structure referred to as a File Info Block and
retrieves information about the file or drawer requested. The
information supplied contains data such as file type, file size or
creation date etc. The three 32 bit numbers which contain the creation
date can be placed in the array TIME() and the Procedure CALC_DATE can
be used to convert them.
Reserve As Work 10,260
We require 260 bytes of memory for the File
Info Block.
_MODE=-2
There are two types of locks: reading or
writing. We set the mode to ACCESS_READ
which is equal to -2.
_EXAMINE=-102
The Examine function 'dos.library' offset is
-102.
_LOCK=-84
The Lock function 'dos.library' offset is -84.
_UNLOCK=-90
The UnLock function 'dos.library' offset is -90.
Dreg(1)=Varptr(NAME$)
Put the address of the variable NAME$ in data
register D1. NAME$ holds the name of the file or
drawer we wish to examine.
Dreg(2)=Varptr(_MODE)
Put the access mode into data register D2.
FILELOCK=Doscall(_LOCK)
Call Lock. FILELOCK should now hold the lock to
the file we require. This prevents other
programs from altering our file while we have
access.
Dreg(1)=FILELOCK
Place this lock into register D1.
Dreg(2)=Start(10)
Tell the function where to place the File Info
Block.
R=Doscall(_EXAMINE)
Call Examine. The 260 bytes reserved in Bank 10
should now contain the data retrieved about our
file by the Examine function.
DREG(1)=FILELOCK
Once we have finished with the file it is
considered polite to release our lock and thus
R=Doscall(_UNLOCK)
give other programs full access to it.
e.g.
EXAMINE["AMOS1.3"]
'
TIME(1)=Leek(Start(10)+132)
TIME(2)=Leek(Start(10)+136)
TIME(3)=Leek(Start(10)+140)
CALC_DATE
Print "Creation Date :-";Param$
'
Print "FileName : ";
For X=8 To 108
Print Chr$(Peek(Start(10)+X));
Next
Print
Print "Disk Key : ";Leek(Start(10))
Print "Dir Type : ";Leek(Start(10)+4)
Print "Protection: ";Bin$(Leek(Start(10)+116),8)-"%"
Print "Entry Type: ";Leek(Start(10)+120)
Print "File Size : ";Leek(Start(10)+124)
Print "Num Blocks: ";Leek(Start(10)+128)
===================================================================
To include in your own programs, simply cut and merge as
ASCII.
Procedure EXAMINE[NAME$]
Erase 10
Reserve As Work 10,260
_MODE=-2
_EXAMINE=-102
_LOCK=-84
_UNLOCK=-90
Dreg(1)=Varptr(NAME$)
Dreg(2)=Varptr(_MODE)
FILELOCK=Doscall(_LOCK)
If FILELOCK
Dreg(1)=FILELOCK
Dreg(2)=Start(10)
R=Doscall(_EXAMINE)
DREG(1)=FILELOCK
R=Doscall(_UNLOCK)
End If
End Proc
Info
This function provides such information as disk size and the number of
blocks used or free and places it in a structure referred to as an
InfoData structure.
Reserve As Work 10,40
We require 40 bytes of memory for the
InfoData structure.
_MODE=-2
There are two types of locks: reading or
writing. We set the mode to ACCESS_READ
which is equal to -2.
_INFO=-114
The Info function 'dos.library' offset is -114.
_LOCK=-84
The Lock function 'dos.library' offset is -84.
_UNLOCK=-90
The UnLock function 'dos.library' offset is -90.
Dreg(1)=Varptr(NAME$)
Put the address of the variable NAME$ in data
register D1.
Dreg(2)=Varptr(_MODE)
Put the access mode into data register D2.
FILELOCK=Doscall(_LOCK)
Call Lock. FILELOCK should now hold the lock to
the file we require. This prevents other
programs from altering our file while we have
access.
Dreg(1)=FILELOCK
Place this lock into register D1.
Dreg(2)=Start(10)
Tell the function where to place the InfoData
structure.
R=Doscall(_INFO)
Call Info. The 40 bytes reserved in Bank 10
should now contain the data retrieved about our
disk by the Info function.
DREG(1)=FILELOCK
Once we have finished with the file it is
considered polite to release our lock and thus
R=Doscall(_UNLOCK)
give other programs full access to it.
e.g.
INFO["df0:"]
Print "NumSoftErrors: ";Leek(Start(10))
Print "Unit Number: ";Leek(Start(10)+4)
Print "Disk State: ";Leek(Start(10)+8)
Print "Num Blocks: ";Leek(Start(10)+12)
Print "Blocks Used: ";Leek(Start(10)+16)
Print "Bytes per Block: ";Leek(Start(10)+20)
Print "Disk Type: ";Leek(Start(10)+24)
Print "VolumeNode: ";Leek(Start(10)+28)
Print "In Use: ";Leek(Start(10)+32)
===================================================================
To include in your own programs, simply cut and merge as
ASCII.
Procedure INFO[NAME$]
Erase 10
Reserve As Work 10,40
_MODE=-2
_LOCK=-84
_UNLOCK=-90
_INFO=-114
Dreg(1)=Varptr(NAME$)
Dreg(2)=Varptr(_MODE)
FILELOCK=Doscall(_LOCK)
Dreg(1)=FILELOCK
Dreg(2)=Start(10)
R=Doscall(_INFO)
Dreg(1)=FILELOCK
R=Doscall(_UNLOCK)
End Proc
(( 27 )) (( 27 )) (( 27 )) (( 27 )) (( 27 )) (( 27 )) (( 27 )) (( 27 ))